﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace ShevaEngine.Core.Modules.Models
{
    /// <summary>Sheva model class.</summary>
    public class ShevaModel
    {
        /// <summary>Vertex buffer.</summary>
        [ContentSerializerIgnore]
        public List<VertexBuffer> VertexBuffers;
        /// <summary>Index buffer.</summary>
        [ContentSerializerIgnore]
        public List<IndexBuffer> IndexBuffers;
        /// <summary>Buffery.</summary>
        public List<ShevaModelBuffer> Buffers;        
        /// <summary>Meshes.</summary>
        public ShevaMesh[] Meshes;
        ///// <summary>Popiry materiaulu.</summary>
        //public List<MaterialDescription> Materials;
        /// <summary>Inverse reference pose transforms.</summary>
        public SkinInfoCollection[] SkinInfo;
        /// <summary>Animations.</summary>
        public AnimationInfoCollection Animations;        
        // Summary:
        //     Gets a collection of ModelBone objects which describe how each mesh in the
        //     Meshes collection for this model relates to its parent mesh.
        public ModelBoneCollection Bones { get; set; }        
        //
        // Summary:
        //     Gets the root bone for this model.
        public ModelBone Root { get; set; }
        
        /// <summary>Bounding box.</summary>
        public BoundingBox BoundingBox { get; set; }

        /// <summary>
        /// Konstruktor.
        /// </summary>
        public ShevaModel()
        {
            

            
        }

        /// <summary>
        /// Metoda provede inicizalizaci modelu.
        /// </summary>
        public void Initialize()
        {
            this.VertexBuffers = new List<VertexBuffer>();
            this.IndexBuffers = new List<IndexBuffer>();

            foreach (ShevaModelBuffer buffer in this.Buffers)
            {
                VertexBuffer newVBO = new VertexBuffer(ShevaEngine.Instance.GraphicsDevice, new VertexDeclaration(buffer.VertexElements), buffer.VerticesCount, BufferUsage.None);
                newVBO.SetData<Byte>(buffer.VertexBufferContent.ToArray());
                this.VertexBuffers.Add(newVBO);

                buffer.VertexBufferContent.Clear();
                buffer.VertexBufferContent = null;

                IndexBuffer newIBO = new IndexBuffer(ShevaEngine.Instance.GraphicsDevice, buffer.ElementSize, buffer.IndicesCount, BufferUsage.None);
                newIBO.SetData<Byte>(buffer.IndexBufferContent.ToArray());
                this.IndexBuffers.Add(newIBO);

                buffer.IndexBufferContent.Clear();
                buffer.IndexBufferContent = null;               
            }

            this.Buffers.Clear();
            this.Buffers = null;

            foreach (ShevaMesh mesh in this.Meshes)
                mesh.Init(this);
        }

        ///// <summary>
        ///// Metoda vrati viditelne objekty.
        ///// </summary>
        ///// <param name="rState"></param>
        ///// <param name="visibleObjects"></param>
        //public void GetVisibleObjects(RendererState rState, RenderingPipeline pipeline,
        //    Matrix transformation)
        //{
        //    foreach (ShevaMesh mesh in this.Meshes)
        //        mesh.GetVisibleObjects(rState, pipeline, transformation);
        //}

        // Summary:
        //     Copies a transform of each bone in a model relative to all parent bones of
        //     the bone into a given array.
        //
        // Parameters:
        //   destinationBoneTransforms:
        //     The array to receive bone transforms.
        public void CopyAbsoluteBoneTransformsTo(Matrix[] destinationBoneTransforms)
        {
            throw new NotImplementedException();
        }

        // Summary:
        //     Copies an array of transforms into each bone in the model.
        //
        // Parameters:
        //   sourceBoneTransforms:
        //     An array containing new bone transforms.
        public void CopyBoneTransformsFrom(Matrix[] sourceBoneTransforms)
        {
            throw new NotImplementedException();
        }

        // Summary:
        //     Copies each bone transform relative only to the parent bone of the model
        //     to a given array.
        //
        // Parameters:
        //   destinationBoneTransforms:
        //     The array to receive bone transforms.
        public void CopyBoneTransformsTo(Matrix[] destinationBoneTransforms)
        {
            throw new NotImplementedException();
        }

        // Summary:
        //     Render a model after applying the matrix transformations.
        //
        // Parameters:
        //   world:
        //     A world transformation matrix.
        //
        //   view:
        //     A view transformation matrix.
        //
        //   projection:
        //     A projection transformation matrix.
        public void Draw(Matrix world, Matrix view, Matrix projection)
        {
            throw new NotImplementedException();
        }
    }
}
